/**
 * @description 解析宏天动态表单对象，并转换输出成本项目表单配置对象的类
 */
import Vue from 'vue'

class HontianForm {
    constructor() {
        /**
         * 规则变量的定义 ：采用Array[Object] 类型的变量做规则定义
         * 
         * JOSN对象拆解深度 由disassembleRuleList长度决定，
         * 待提取的属性名称 由disassembleRuleList项的executeeName决定，
         * 待提取的属性的数据类型 由disassembleRuleList项的executeeType决定，
         * 每个层级提取的属性值缓存 放于disassembleRuleList项的executeeValue变量上;
         * */
        this.disassembleRuleList = [{
            executeeName: 'list',
            executeeType: 'Array',
            executeeValue: [],
        },
        {
            executeeName: 'columns',
            executeeType: 'Array',
            executeeValue: [],
        },
        {
            executeeName: 'list',
            executeeType: 'Array',
            executeeValue: [],
        },
        ]

        this._parts = [] // 拆解出来的宏天表单项源数据

        this._targetFrom = { //最终目标构建自定义的表单配置对象
            field: {},
            property: [],
        }

        this._translationTable = {
            /**
             * 对照表定义
             * key: value
             * 宏天表单ctrlType属性  ： 基座表单组件定制对象type属性
             */
            // 已定义的输入类型
            input: 'text', // 普通输入框
            textarea: 'textarea',  // 加高的文本输入域
            number: 'number', // 数值类型输入框
            radio: 'region', // 单选项输入类型
            checkbox: 'multiChoose', // 多选项选择器
            date: 'date',// 日期选择器
            time: 'time',// 时分秒选择器
            selector: 'selector', // 单选选择器
            select: 'selector',
            dropdown: 'multiSelector',
            dic: 'selector',
            amap: 'location', // 地图选点

            // 未定义的输入类型
            property_text: "", // 属性文本输入类型
            currency: "", // 货币数值输入类型
            dialog: "", // 弹窗输入类型
            switch: "", // 开关类型
            tag: "", // 标签选择类型
            related_process: "", // 相关流程选择类型
            autocomplete: "",// 输入建议类型 ？？
            signature: "",// 签章输入类型
        },

            // 自定义表单的配置项模板，并且初始属性的值设置为宏天配置对象对应的属性层级名称(#号开头)，以便注入方法遍历锁定属性值，回填模板属性值
            this._selfTemplates = {
                text: {
                    text: '#title',
                    type: 'text',
                    value: '#name',
                    valueShow: '',
                    validate: false,
                    warn: false
                },
                number: {
                    text: '#title',
                    type: 'number',
                    value: '#name',
                    valueShow: '',
                    validate: false,
                    warn: false
                },
                tel: {
                    text: '#title',
                    type: 'tel',
                    value: '#name',
                    valueShow: '',
                    validate: false,
                    warn: false
                },
                ID: {
                    text: '#title',
                    type: 'ID',
                    value: '#name',
                    valueShow: '',
                    validate: false,
                    warn: false
                },
                click: {
                    text: '#title',
                    type: 'click',
                    value: '#name',
                    valueShow: '',
                    validate: false,
                    warn: false
                },
                location: {
                    text: '#title',
                    type: 'location',
                    value: '#name',
                    valueShow: '',
                    validate: false,
                    warn: false
                },
                textarea: {
                    text: '#title',
                    type: 'textarea',
                    value: '#name',
                    maxLength: 200,
                    disabled: false,
                    valueShow: '',
                    validate: true,
                    warn: false
                },
                selector: {
                    text: '#title',
                    type: 'selector',
                    value: '#name',
                    dictionary: '#options#customQuery#conditionfield#defaultValue',
                    rangekey: 'text',
                    valueShow: '',
                    indexValue: 0,
                    getKey: 'value',
                    options: [],
                    validate: true,
                    warn: false
                },
                multiSelector: {
                    text: '#title',
                    type: 'multiSelector',
                    value: '#name',
                    getKey: 'key',
                    valueShow: '',
                    column: 5,
                    showValue: {
                        key: '',
                        value: ''
                    },
                    options: [],
                    defaultPicker: [0, 0, 0, 0, 0],
                    validate: true,
                    warn: false
                },
                multiChoose: {
                    text: '#title',
                    type: 'multiChoose',
                    value: '#name',
                    getKey: 'key',
                    showValue: {
                        key: '',
                        value: ''
                    },
                    valueShow: '',
                    dictionary: '',
                    options: [],
                    validate: true,
                    warn: false
                },
                radio: {
                    text: '#title',
                    type: 'radio',
                    value: '#name',
                    placeholder: '',
                    valueShow: '',
                    getKey: 'key',
                    showValue: {
                        key: '',
                        value: ''
                    },
                    dictionary: '',
                    options: [],
                    validate: true,
                    warn: false
                },
                data: {
                    text: '#title',
                    type: 'date',
                    value: '#name',
                    valueShow: '',
                    column: 'day',
                    start: '',
                    end: '',
                    validate: false,
                    warn: false
                },
                time: {
                    text: '#title',
                    type: 'time',
                    value: '#name',
                    valueShow: '',
                    start: '',
                    end: '',
                    validate: true,
                    warn: false
                }
            }
    }

    /**
     * 分离器 分发方法
     * @param {Array | Object | String} rule    自定义的拆解规则
     * @param {Array | Object} sourceData       待拆解的源数据
     */
    separatorDistribute(sourceData, rule = this.disassembleRuleList) {

        switch (typeof rule) {
            // 字符类型则提取目标中同名的相应属性
            case "string":
                break;
            // 对象类型
            case "object":
                if (Array.isArray(rule)) {
                    // 列表类型： 根据列表长度定义拆解深度，根据列表项executeeName值取同名属性
                    this.arrayRuleSeparator(rule, sourceData);
                } else {
                    // 对象类型： 根据对象属性key，取对应key同名属性值注入规则对象的属性
                    break;
                }
        }
    }
    // JSON 拆解方法分发器
    JSONAdapter(JSONSource, disassembleRule) {
        if (Array.isArray(JSONSource)) {
            return this.JSONArrayDisassemble(JSONSource, disassembleRule);
        } else if (typeof JSONSource == 'object') {
            return this.JSONObjectDisassemble(JSONSource, disassembleRule);
        }
    }
    // JSON 列表数据的拆解方法
    JSONArrayDisassemble(executee, rule) {
        let catchValue = [];
        executee.forEach((item, index) => {
            if (item[rule.executeeName]) {
                catchValue = catchValue.concat(item[rule.executeeName]);
            }
        })
        return catchValue;
    }
    // JSON 对象数据的拆解方法
    JSONObjectDisassemble(executee, rule) {
        return executee[rule.executeeName];
    }
    // 拆解抽取宏天表单配置项的列表, rule为array[object]类型的规则
    arrayRuleSeparator(rules, sourceData) {
        rules.forEach((rule, index) => {
            if (!index) {
                rule.executeeValue = this.JSONAdapter(sourceData, rule);
            } else if (rules[index - 1].executeeValue.length) {
                rule.executeeValue = this.JSONAdapter(rules[index - 1]
                    .executeeValue, rule);
            }

            if (index >= rules.length - 1) {
                this._setParts(rules);
            }
        })
    }

    /**
     * 组装器方法，用于匹配自定义表单项模板，注入宏天同类型表单项配置属性
     * @param {Array} translationTable  用作翻译宏表单项控制类型与自定义模板的类型
     * @param {Object} selfTemplates    自定义表单项配置对象的模板集
     * @param {Array} hontianFormSource 宏天接口请求回来拆解完成的表单项源数据列表
     */
    assembleTarget(translationTable = this._getTranslationTable(), selfTemplates = this._getSelfTemplates(), hontianFormSource = this._getParts()) {
        this._targetFrom.field = {};
        this._targetFrom.property = [];
        let hontianItems = [].concat(hontianFormSource[0].executeeValue);
        hontianItems.forEach(hontianItem => {
            let template = selfTemplates[translationTable[hontianItem.ctrlType]]
            console.log("翻译模板名：", translationTable[hontianItem.ctrlType])
            console.log("选取的模板：", template)

            this._setTargetFrom(this.injection(template, hontianItem));
        })
    }
    //根据自定义模板初始属性值，提取宏天配置对象的属性值，并注入覆盖初始属性值
    injection(selfTemplate, hontianFromItem) {
        let selfTemplateKeys = Object.keys(selfTemplate);
        let catchTemplate = { ...selfTemplate };
        selfTemplateKeys.forEach(selfKey => {
            if (typeof selfTemplate[selfKey] == 'string' && selfTemplate[selfKey].indexOf("#") != -1) {
                let layers = selfTemplate[selfKey].split("#").splice(1);
                console.log("layers:", layers);
                let catchLayer = hontianFromItem[layers[0]];
                layers.forEach((layer, index) => {
                    if (index > 0 && index < layers.length - 1) {
                        catchLayer = catchLayer[layer];
                    } else {
                        if (Array.isArray(catchLayer)) {
                            catchTemplate[selfKey] = catchLayer[0][layer];
                        } else if (!index) {
                            catchTemplate[selfKey] = catchLayer;
                        } else {
                            catchTemplate[selfKey] = catchLayer[layer];
                        }
                    }
                })
                // catchTemplate[selfKey] = hontianFromItem[selfTemplate[selfKey].split("#")[0]];
            }
        })
        console.log("重构的表单项：", catchTemplate);
        return { ...catchTemplate };
    }


    /**
     * 属性的
     * get set 方法域 
     */
    // parts 属性的set get方法
    _setParts(val) {
        this._parts = [].concat(val);
    }
    _getParts() {
        return [].concat(this._parts).reverse();
    }

    _getTranslationTable() {
        return this._translationTable;
    }

    _getSelfTemplates() {
        return this._selfTemplates;
    }

    _setTargetFrom(val) {
        this._targetFrom.property.push(val);
        this._targetFrom.field[val.value] = val.valueShow;
    }
    _getTargetFrom() {
        return { ...this._targetFrom }
    }
}

export default HontianForm